package ecom.shell.commandsImpl;

import ecom.shell.commandsImpl.OutputCommandImpl.Outputs;
import ecom.shell.exception.UnknownArgumentException;
import java.io.PrintStream;
import java.util.StringTokenizer;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import shell.ShellCommand;
import shell.ShellContext;

public class LanguageCommandsImpl implements ShellCommand {

    private ShellContext _context = null;

    public enum Languages {

        ENGLISH("en"), FRENCH("fr"), SPANISH("sp"), ITALIAN("it");
        private String name;

        Languages(String name) {
            this.name = name;
        }

        public static Languages getDefault() {
            return FRENCH;
        }

        public static Languages get(String s) throws UnknownArgumentException {
            for (Languages l : Languages.values()) {
                if (s.equals(String.valueOf(l))) {
                    return l;
                }
            }
            throw new UnknownArgumentException("Error : " + s + " is an unknown argument");
        }

        public String getName() {
            return this.name;
        }
    };

    public LanguageCommandsImpl(ShellContext context) {
        _context = context;
    }

    @Override
    public String getName() {
        return "language";
    }

    @Override
    public String getUsage() {
        StringBuffer sb = new StringBuffer();

        Languages[] v = Languages.values();

        for (int i = 0; i < v.length; ++i) {
            sb.append(v[i]);
            if (i < v.length - 1) {
                sb.append("|");
            }
        }
        return "language " + sb;
    }

    @Override
    public String getShortDescription() {
        return "Set language\n";
    }

    @Override
    public String execute(String cmdline, PrintStream out, PrintStream err) {
        StringBuilder res = new StringBuilder();
        StringTokenizer st = new StringTokenizer(cmdline, " ");
        st.nextToken();

        if (st.countTokens() == 0) {
            try {
                Languages[] symbols = Languages.values();
                Outputs currentOutput = (Outputs) _context.getVar("output");
                return printList(out, symbols, currentOutput);
            } catch (Exception ex) {
                err.println("Error with currencies display");
            }
        } else if (st.countTokens() == 1) {
            String newLanguage = st.nextToken().trim();

            Languages l;
            try {
                l = Languages.get(newLanguage);
                res.append("New Language : ").append(String.valueOf(l)).append(" - ").append(l.getName());
                _context.setVar("language", l);

            } catch (UnknownArgumentException ex) {
                res.append(ex).append(" for ").append(getName()).append(" command");
                err.println(ex + " for '" + getName() + "' command");
            }
        } else {
            err.println(EcomCommandsConstantes.INCORRECT_NUMBER_ARGS);
        }
        return res.toString();
    }

    private String printList(PrintStream out, Languages[] symbols, Outputs currentOutput) {
        StringBuilder res = new StringBuilder();
        if (currentOutput.equals(Outputs.XML)) {
            Element languages = new Element("languages");
            org.jdom.Document document = new Document(languages);

            for (int i = 0; i < symbols.length; ++i) {
                languages.addContent(buildXMLNode(symbols[i]));
            }
            XMLOutputter sortie = new XMLOutputter(Format.getPrettyFormat());
            res.append(sortie.outputString(document));
        } else if (currentOutput.equals(Outputs.TEXT)) {
            for (int i = 0; i < symbols.length; ++i) {
                res.append("\t").append(String.valueOf(symbols[i])).append(" - ").append(symbols[i].getName()).append("\n");
            }
        } else {
            res.append("Output format '").append(currentOutput).append("' is not implementing for this command");
        }
        return res.toString();
    }

    private Element buildXMLNode(Languages l) {
        Element language = new Element("language");

        Element name = new Element("name");
        Attribute id = new Attribute("id", String.valueOf(l));
        name.setAttribute(id);
        name.setText(l.getName());
        language.addContent(name);

        return language;
    }
}
